package interpreter

// Environment 表示作用域环境
type Environment struct {
	store     map[string]Object
	outer     *Environment
	constants map[string]bool
}

// NewEnvironment 创建一个新的环境
func NewEnvironment() *Environment {
	s := make(map[string]Object)
	c := make(map[string]bool)
	return &Environment{store: s, constants: c, outer: nil}
}

// NewEnclosedEnvironment 创建一个新的封闭环境
func NewEnclosedEnvironment(outer *Environment) *Environment {
	env := NewEnvironment()
	env.outer = outer
	return env
}

// Get 从环境中获取值
func (e *Environment) Get(name string) (Object, bool) {
	obj, ok := e.store[name]
	if !ok && e.outer != nil {
		obj, ok = e.outer.Get(name)
	}
	return obj, ok
}

// Set 设置环境中的值
func (e *Environment) Set(name string, val Object) Object {
	// 如果当前环境中已定义为常量，不允许修改
	if isConst, ok := e.constants[name]; ok && isConst {
		warn("常量 %s 不允许修改", name)
		return val
	}

	// 在当前环境中设置变量
	e.store[name] = val
	return val
}

// SetConst 设置常量
func (e *Environment) SetConst(name string, val Object) Object {
	e.store[name] = val
	e.constants[name] = true
	return val
}

// Delete 从环境中删除值
func (e *Environment) Delete(name string) bool {
	_, exists := e.store[name]
	if exists {
		delete(e.store, name)
		return true
	}
	return false
}
